/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean;

import entity.FnBBranchEntity;
import entity.FnBProductEntity;
import entity.MealEntity;
import entity.PriceControlEntity;
import entity.ProductAvailabilityEntity;
import entity.ProductEntity;
import entity.SetMealEntity;
import entity.StakeholderEntity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import session.stateful.ProductSessionBean;
import exception.PriceControlException;

/**
 *
 * @author Dell
 */
@ManagedBean
@SessionScoped
public class ProductManagerBean {

    @EJB
    ProductSessionBean productSessionBean;
    private ProductEntity selectedProduct;
    private PriceControlEntity selectedPriceControl = new PriceControlEntity();
    private PriceControlEntity priceControl = new PriceControlEntity();
    private List<PriceControlEntity> listOfPriceControl = new ArrayList<PriceControlEntity>();
    private List dayOfWeek = new ArrayList();
    private List timeOfDay = new ArrayList();
    private boolean reloadPriceControl;
    private boolean reloadProductAvail;
    private ProductAvailabilityEntity[] selectedAvail;
    private List<ProductAvailabilityEntity> listOfAvail;
    private long productId;
    private FnBBranchEntity branch;
    private StakeholderEntity stakeholder;
    private List<FnBProductEntity> listOfProduct;
    private MealEntity meal;
    private SetMealEntity setMeal;
    private boolean load = true;
    private FacesContext ctx = FacesContext.getCurrentInstance();

    public ProductManagerBean() {
        reloadPriceControl = true;
        reloadProductAvail = true;
        dayOfWeek.add(new SelectItem(0, "Default"));
        dayOfWeek.add(new SelectItem(1, "Sunday"));
        dayOfWeek.add(new SelectItem(2, "Monday"));
        dayOfWeek.add(new SelectItem(3, "Tuesday"));
        dayOfWeek.add(new SelectItem(4, "Wednesday"));
        dayOfWeek.add(new SelectItem(5, "Thursday"));
        dayOfWeek.add(new SelectItem(6, "Friday"));
        dayOfWeek.add(new SelectItem(7, "Saturday"));
        dayOfWeek.add(new SelectItem(8, "Specific Date"));

        timeOfDay.add(new SelectItem(0, "12AM"));

        for (int i = 1; i <= 11; i++) {
            timeOfDay.add(new SelectItem(i, i + "AM"));
        }

        timeOfDay.add(new SelectItem(12, "12PM"));
        for (int i = 1; i <= 11; i++) {
            timeOfDay.add(new SelectItem(i + 12, i + "PM"));
        }
        timeOfDay.add(new SelectItem(24, "Midnight"));
    }

    public void addPriceControl(ActionEvent event) {
        if (priceControl.getStartTime() >= priceControl.getEndTime()) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Add Unsuccessfully: start time must be smaller than end time", ""));
            return;
        }

        try {
            productSessionBean.addPriceControl(selectedProduct.getId(), priceControl);
            priceControl = new PriceControlEntity();
            reloadPriceControl = true;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Add Successfully", ""));
        } catch (PriceControlException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Add Unsuccessfully: " + ex.getMessage(), ""));
        }
    }

    public void removePriceControl(long id) {
        productSessionBean.removePriceControl(id);
        reloadPriceControl = true;
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                FacesMessage.SEVERITY_INFO, "Remove Successfully", ""));
    }

    public void editPriceControl(RowEditEvent event) {
        reloadPriceControl = true;
        PriceControlEntity temp = (PriceControlEntity) event.getObject();
        if (temp.getStartTime() >= temp.getEndTime()) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Edit Unsuccessfully: Start time must be smaller than end time", ""));
            return;
        }

        try {
            productSessionBean.editPriceControl(temp);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Edit Successfully", ""));

        } catch (PriceControlException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Edit Unsuccessfully: " + ex.getMessage(), ""));
        }
    }

    public void editAvail(ActionEvent event) {
        productSessionBean.editAvail(selectedProduct, selectedAvail);
        reloadProductAvail = true;
    }

    public void initPriceControl(PhaseEvent event) throws IOException {
        HttpServletRequest servletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        String productType = servletRequest.getRequestURI();

        if (load) {
            if (!checkProduct(productType)) {
                return;
            }
            load = false;
        }

        if (reloadPriceControl) {
            listOfPriceControl = productSessionBean.getListOfPriceControl(selectedProduct.getId());
            Collections.sort(listOfPriceControl, new PriceControlEntity());
            System.out.println("Reload Price COntrol");
            reloadPriceControl = false;

            if (reloadProductAvail) {
                selectedAvail = productSessionBean.retrieveAvailListByProductId(selectedProduct.getId());
                listOfAvail = productSessionBean.retrieveAllAvailList();
                System.out.println("Reload Product Avail");
                reloadProductAvail = false;
            }
        }
    }

    public void selectProduct(SelectEvent event) {
        selectedProduct = (ProductEntity) event.getObject();

        reloadPriceControl = true;
        reloadProductAvail = true;
    }

    public void initGetProduct(PhaseEvent event) {
        branch = (FnBBranchEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedBranch");
        listOfProduct = productSessionBean.getAllProductByBranchId(branch.getId());
    }

    public ProductEntity getSelectedProduct() {
        return selectedProduct;
    }

    public void setSelectedProduct(ProductEntity selectedProduct) {
        this.selectedProduct = selectedProduct;
    }

    public long getProductId() {
        return productId;
    }

    public void setProductId(long productId) {
        this.productId = productId;
    }

    public List<PriceControlEntity> getListOfPriceControl() {
        return listOfPriceControl;
    }

    public void setListOfPriceControl(List<PriceControlEntity> listOfPriceControl) {
        this.listOfPriceControl = listOfPriceControl;
    }

    public PriceControlEntity getPriceControl() {
        return priceControl;
    }

    public void setPriceControl(PriceControlEntity priceControl) {
        this.priceControl = priceControl;
    }

    public List getDayOfWeek() {
        return dayOfWeek;
    }

    public void setDayOfWeek(List dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }

    public List getTimeOfDay() {
        return timeOfDay;
    }

    public void setTimeOfDay(List timeOfDay) {
        this.timeOfDay = timeOfDay;
    }

    public PriceControlEntity getSelectedPriceControl() {
        return selectedPriceControl;
    }

    public void setSelectedPriceControl(PriceControlEntity selectedPriceControl) {
        this.selectedPriceControl = selectedPriceControl;
    }

    public ProductAvailabilityEntity[] getSelectedAvail() {
        return selectedAvail;
    }

    public void setSelectedAvail(ProductAvailabilityEntity[] selectedAvail) {
        this.selectedAvail = selectedAvail;
    }

    public List<ProductAvailabilityEntity> getListOfAvail() {
        return listOfAvail;
    }

    public void setListOfAvail(List<ProductAvailabilityEntity> listOfAvail) {
        this.listOfAvail = listOfAvail;
    }

    public FnBBranchEntity getBranch() {
        return branch;
    }

    public void setBranch(FnBBranchEntity branch) {
        this.branch = branch;
    }

    public List<FnBProductEntity> getListOfProduct() {
        return listOfProduct;
    }

    public void setListOfProduct(List<FnBProductEntity> listOfProduct) {
        this.listOfProduct = listOfProduct;
    }

    public boolean checkStakeholder() throws IOException {
        stakeholder = (StakeholderEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholder");
        if (stakeholder == null || stakeholder.getId() == null) {
            String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/StakeholderLogin.xhtml");
            return false;
        }
        return true;
    }

    public boolean checkBranch() throws IOException {
        if (!checkStakeholder()) {
            return false;
        }
        branch = (FnBBranchEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedBranch");
        if (branch == null || branch.getId() == null) {
            String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/stakeholder/StakeholderViewAllBranch.xhtml");
            return false;
        }
        return true;
    }

    public boolean checkProduct(String productType) throws IOException {
        if (!checkBranch()) {
            return false;
        }
        ProductEntity temp = selectedProduct;
        selectedProduct = (ProductEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedProduct");
        String serverName = ctx.getExternalContext().getRequestServerName();
        int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
        String contextPath = ctx.getExternalContext().getRequestContextPath();
        if (selectedProduct == null || selectedProduct.getId() == null) {
            if (productType.indexOf("SetMeal") != - 1) {
                ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/stakeholder/StakeholderViewSetMeals.xhtml");
            } else {
                ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/stakeholder/StakeholderViewMeals.xhtml");
            }
            return false;
        }

        if (temp == null || !temp.equals(selectedProduct)) {
            reloadPriceControl = true;
            reloadProductAvail = true;
        }
        return true;
    }
}
